/*
 * Copyright 2023 The Backstage Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import fs from 'fs-extra';
import YAML from 'js-yaml';
import chalk from 'chalk';
import { paths as cliPaths } from '../../../../../lib/paths';
import { TS_SCHEMA_PATH } from '../../../../../lib/openapi/constants';
import { promisify } from 'util';
import { exec as execCb } from 'child_process';
import { getPathToCurrentOpenApiSpec } from '../../../../../lib/openapi/helpers';

const exec = promisify(execCb);

async function generate() {
  const openapiPath = await getPathToCurrentOpenApiSpec();
  const yaml = YAML.load(await fs.readFile(openapiPath, 'utf8'));

  const tsPath = cliPaths.resolveTarget(TS_SCHEMA_PATH);

  // The first set of comment slashes allow for the eslint notice plugin to run
  // with onNonMatchingHeader: 'replace', as is the case in the open source
  // Backstage repo. Otherwise the auto-generated comment will be removed by the
  // lint call below.
  await fs.writeFile(
    tsPath,
    `//

// ******************************************************************
// * THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. *
// ******************************************************************
import {createValidatedOpenApiRouter} from '@backstage/backend-openapi-utils';
export const spec = ${JSON.stringify(yaml, null, 2)} as const;
export const createOpenApiRouter = async (
  options?: Parameters<typeof createValidatedOpenApiRouter>['1'],
) => createValidatedOpenApiRouter<typeof spec>(spec, options);
`,
  );

  await exec(`yarn backstage-cli package lint --fix ${tsPath}`);
  if (await cliPaths.resolveTargetRoot('node_modules/.bin/prettier')) {
    await exec(`yarn prettier --write ${tsPath}`, {
      cwd: cliPaths.targetRoot,
    });
  }
}

export async function command(): Promise<void> {
  try {
    await generate();
    console.log(chalk.green('Generated all files.'));
  } catch (err) {
    console.log(chalk.red(`OpenAPI server stub generation failed.`));
    console.log(err.message);
    process.exit(1);
  }
}
